#include "fs.h"
#include "fat32.h"
#include "stdio.h"
#include "string.h"
#include "panic.h"
#include "proc.h"

// store all the open file
struct file_info file_table[FILE_TABLE_SIZE];

// current directory
struct file_info *cur_dir;

/* @brief: init the devs, stdio stdout stderr
 */
void dev_init() {
	file_table[stdin].type = file_table[stdout].type = file_table[stderr].type = DEVICE;
	strcpy(file_table[stdin].fname, "stdio");
	strcpy(file_table[stdout].fname, "stdout");
	strcpy(file_table[stderr].fname, "stderr");
}

/* @brief: init the file system
 */
void fs_init() {
	int i;
	for (i = 4; i < FILE_TABLE_SIZE; ++i) {
		file_table[i].type = UNUSED;
	}
	dev_init();
	fat32_init();
}

/* @brief: alloc a file
 */
struct file_info *alloc_file_info() {
	int i;
	for (i = 4; i < FILE_TABLE_SIZE; ++i) {
		if (file_table[i].type == UNUSED) {
			return &file_table[i];
		}
	}
	panic("alloc_file_info: too many open files.\n");
	return NULL;
}

/* @brief: open a file
 * @param fd: the file descriptor of the file-located directory
 * @param filename: file name, can be relative or absolute
 * @param flags:
 * @param mode:
 * @return: fd of the opened file, -1 if failed
 * @bug: the same file may uses more than one struct file_info
 * 	if different process open it
 */
int fs_openat(int fd, char *filename, int flags, int mode) {
	return fat32_openat(fd, filename, flags, mode);
}

/* @brief: read from a file
 * @param fd: file fd
 * @param buf: buffer of the content to be read
 * @param size: content size
 * @return: read bytes number
 */
int fs_read(int fd, void *buf, uint32 size) {
	return fat32_read(fd, buf, size);
}

/* @breif: close a file
 * @param fd: file descriptor to be closed
 * @return: 0 successfully, -1 failed
 */
int fs_close(int fd) {
	if (cur_proc->fd_table[fd] == NULL) {
		return -1;
	}
	cur_proc->fd_table[fd]->type = UNUSED;
	cur_proc->fd_table[fd] = NULL;
	return 0;
}


